package com.swiftops.common.service;

import com.swiftops.common.core.Mapper;
import com.swiftops.common.model.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Condition;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.Date;
import java.util.List;

/**
 * 基于通用MyBatis Mapper插件的Service接口的实现
 */
@Slf4j
public abstract class AbstractService<T> implements Service<T> {

    @Autowired
    protected Mapper<T> mapper;

    @Autowired
    private ThreadLocalUserService threadLocalUserService;

    /**
     * 当前泛型真实类型的Class
     */
    private Class<T> modelClass;

    @SuppressWarnings(value = {"unckecked"})
    public AbstractService() {
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        modelClass = (Class<T>) pt.getActualTypeArguments()[0];
    }

    @Override
    public int insertSelective(T model) {
        this.insertModelAddInfo(model);
        return mapper.insertSelective(model);
    }

    @Override
    public int insertUseGeneratedKeys(T model) {
        this.insertModelAddInfo(model);
        return mapper.insertUseGeneratedKeys(model);
    }


    @Override
    public int insertList(List<T> models) {
        for (T model : models) {
            this.insertModelAddInfo(model);
        }
        int total = 0;
        for (T model : models) {
            total = total + mapper.insertSelective(model);
        }
        return total;
        //return mapper.insertList(models);
    }

    @Override
    public int deleteByPrimaryKey(String id) {
        return mapper.deleteByPrimaryKey(id);
    }

    @Override
    public int deleteByIds(String ids) {
        return mapper.deleteByIds(ids);
    }

    @Override
    public int deleteByCondition(Condition condition) {
        return mapper.deleteByCondition(condition);
    }

    @Override
    public int updateByPrimaryKeySelective(T model) {
        this.updateModelAddInfo(model);
        return mapper.updateByPrimaryKeySelective(model);
    }

    @Override
    public int updateByPrimaryKey(T model) {
        this.updateModelAddInfo(model);
        return mapper.updateByPrimaryKey(model);
    }

    @Override
    public int updateByCondition(T model, Condition condition) {
        this.updateModelAddInfo(model);
        return mapper.updateByCondition(model, condition);
    }

    @Override
    public int updateByConditionSelective(T model, Condition condition) {
        this.updateModelAddInfo(model);
        return mapper.updateByConditionSelective(model, condition);
    }

    @Override
    public T selectByPrimaryKey(String id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public List<T> selectByIds(String ids) {
        return mapper.selectByIds(ids);
    }

    @Override
    public List<T> selectByCondition(Condition condition) {
        return mapper.selectByCondition(condition);
    }

    @Override
    public List<T> selectAll() {
        return mapper.selectAll();
    }

    @Override
    public T selectOne(T model) {
        return mapper.selectOne(model);
    }

    @Override
    public List<T> select(T model) {
        return mapper.select(model);
    }

    @Override
    public int selectCount(T model) {
        return mapper.selectCount(model);
    }

    public int selectCountByCondition(Condition condition) {
        return mapper.selectCountByCondition(condition);
    }

    /**
     * 添加实体添加创建人、创建时间、更新人、更新时间
     *
     * @param model 实体对象
     */
    private void insertModelAddInfo(T model) {
        User user = threadLocalUserService.getUser();
        if (user != null) {
            this.addModelInfo(user.getUserId(), model, true);
        } else {
            this.addModelInfo(null, model, true);
        }
    }

    /**
     * 修改实体添加创建人、创建时间、更新人、更新时间
     *
     * @param model 实体对象
     */
    private void updateModelAddInfo(T model) {
        User user = threadLocalUserService.getUser();
        if (user != null) {
            this.addModelInfo(user.getUserId(), model, false);
        } else {
            this.addModelInfo(null, model, false);
        }
    }

    /**
     * 添加实体类的创建人、创建时间、更新人、更新时间
     *
     * @param id       人员ID
     * @param model    实体对象
     * @param isCreate 判断是否创建 false 不是，true 是
     */
    private void addModelInfo(String id, T model, boolean isCreate) {
        Field[] fs = model.getClass().getDeclaredFields();
        try {
            for (Field f : fs) {
                String fieldName = f.getName();
                if (isCreate && "createdBy".equals(fieldName)) {
                    f.setAccessible(true);
                    f.set(model, id);
                }
                if (isCreate && "createdAt".equals(fieldName)) {
                    f.setAccessible(true);
                    f.set(model, new Date());
                }
                if (isCreate && "deleteFlag".equals(fieldName)) {
                    f.setAccessible(true);
                    f.set(model, "0");
                }
                if ("updatedBy".equals(fieldName)) {
                    f.setAccessible(true);
                    f.set(model, id);
                }
                if ("updatedAt".equals(fieldName)) {
                    f.setAccessible(true);
                    f.set(model, new Date());
                }
            }
        } catch (IllegalAccessException e) {
            log.error(e.getMessage());
        }
    }
}
